package pacman.objects;

import pacman.Dijkstra;
import java.awt.Color;
import java.awt.Graphics;

/**
 * This class represents a ghost
 * @author Carlos Massera Filho
 */
public final class Ghost extends Moveable
{
  private Color ghostColor;
  private boolean withFood;
  private int level;

  /**
   * Initiatis the ghost in the posX, posY position, visible, and alive, with health = 1;
   * @param posX
   * @param posY
   */
  public Ghost(float posX, float posY)
  {
    this.health = 1;
    this.maxHealth = 1;
    this.visible = true;
    this.charSize = (float)0.5;

    this.dead = false;
    this.withFood = false;

    this.posX = posX * cellSize + cellSize/2;
    this.posY = posY * cellSize + cellSize/2;
    this.headingAngle = 0;
    this.speed = (float)1;

    this.level = 1;

    //Insert color 
  }

  /**
   * Interprets the ia matrix to run toward the pacman
   * @param ia The runned dijkstra algorithm
   * @param mapSizeX Size of the map
   * @param mapSizeY Size of the map
   * @return true if it was able to walk false otherwise
   */
  public boolean runIAattack(Dijkstra ia, int mapSizeX, int mapSizeY)
  {
    if ((int)(posX - charSize * cellSize / 2) % (int)cellSize < (1 - charSize) * cellSize &&
        (int)(posY - charSize * cellSize/2) % (int)cellSize < (1 - charSize) * cellSize &&
        (int)(posX + charSize * cellSize / 2) % (int)cellSize > charSize * cellSize &&
        (int)(posY + charSize * cellSize/2) % (int)cellSize > charSize * cellSize)
    {
      int aux = (int)(posX + cellSize);
      if (aux >= mapSizeX * cellSize)
        aux = 0;
      if ((ia.getPosistionCost((int)posX, (int)posY) - 1) % 1000 == ia.getPosistionCost(aux, (int)posY) % 1000 && ia.getPosistionCost(aux, (int)posY) != -1)
      {
        headingAngle = (float)0;
        return true;
      }

      aux = (int)(posY - cellSize) ;
      if (aux < 0)
        aux = (mapSizeY - 1) * cellSize;
      if ((ia.getPosistionCost((int)posX, (int)posY) - 1) % 1000 == ia.getPosistionCost((int)posX, aux) % 1000 && ia.getPosistionCost((int)(posX), aux) != -1)
      {
        headingAngle = (float)Math.PI / 2;
        return true;
      }

      aux = (int)(posX - cellSize);
      if (aux < 0)
        aux = (mapSizeX - 1) * cellSize;
      if ((ia.getPosistionCost((int)posX, (int)posY) - 1) % 1000 == ia.getPosistionCost(aux, (int)posY) % 1000 && ia.getPosistionCost(aux, (int)posY) != -1)
      {
        headingAngle = (float)Math.PI;
        return true;
      }

      aux = (int)(posY + cellSize);
      if (aux >= mapSizeY * cellSize)
        aux = 0;
      if ((ia.getPosistionCost((int)posX, (int)posY) - 1) % 1000 == ia.getPosistionCost((int)posX, aux) % 1000 && ia.getPosistionCost((int)(posX), aux) != -1)
      {
        headingAngle = 3 * (float)Math.PI / 2;
        return true;
      }
      return false;
    }
    return true;
  }

  /**
   * Interprets the ia matrix to run away from the pacman
   * @param ia The runned dijkstra algorithm
   * @param mapSizeX Size of the map
   * @param mapSizeY Size of the map
   * @return true if it was able to walk false otherwise
   */
  public boolean runIAescape(Dijkstra ia, int mapSizeX, int mapSizeY)
  {
    if ((int)(posX - charSize * cellSize / 2) % (int)cellSize < (1 - charSize) * cellSize &&
        (int)(posY - charSize * cellSize/2) % (int)cellSize < (1 - charSize) * cellSize &&
        (int)(posX + charSize * cellSize / 2) % (int)cellSize > charSize * cellSize &&
        (int)(posY + charSize * cellSize/2) % (int)cellSize > charSize * cellSize)
    {
      int aux = (int)(posX + cellSize);
      if (aux >= mapSizeX * cellSize)
        aux = 0;
      if ((ia.getPosistionCost((int)posX, (int)posY) + 1) % 1000 == ia.getPosistionCost(aux, (int)posY) % 1000 && ia.getPosistionCost(aux, (int)posY) != -1)
      {
        headingAngle = (float)0;
        return true;
      }

      aux = (int)(posY - cellSize) ;
      if (aux < 0)
        aux = (mapSizeY - 1) * cellSize;
      if ((ia.getPosistionCost((int)posX, (int)posY) + 1) % 1000 == ia.getPosistionCost((int)posX, aux) % 1000 && ia.getPosistionCost((int)(posX), aux) != -1)
      {
        headingAngle = (float)Math.PI / 2;
        return true;
      }

      aux = (int)(posX - cellSize);
      if (aux < 0)
        aux = (mapSizeX - 1) * cellSize;
      if ((ia.getPosistionCost((int)posX, (int)posY) + 1) % 1000 == ia.getPosistionCost(aux, (int)posY) % 1000 && ia.getPosistionCost(aux, (int)posY) != -1)
      {
        headingAngle = (float)Math.PI;
        return true;
      }

      aux = (int)(posY + cellSize);
      if (aux >= mapSizeY * cellSize)
        aux = 0;
      if ((ia.getPosistionCost((int)posX, (int)posY) + 1) % 1000 == ia.getPosistionCost((int)posX, aux) % 1000 && ia.getPosistionCost((int)(posX), aux) != -1)
      {
        headingAngle = 3 * (float)Math.PI / 2;
        return true;
      }
      return false;
    }
    return true;
  }

  /**
   *update information that changes on level up
   */
  public void levelUp(){
    this.level += 1;
    this.maxHealth += 1;
    this.speed += (float)0.2;
  }

  /**
   * If the ghost has eaten a food it returns true and false otherwise
   * @return
   */
  public boolean isWithFood()
  {
    return this.withFood;
  }

  /**
   * Printd the ghost in the screen
   * @param g
   */
  public void render(Graphics g)
  {
    g.setColor(Color.YELLOW);
    g.fillOval((int)(this.posX - charSize * cellSize / 2), (int)(this.posY - charSize * cellSize / 2), (int)(charSize * cellSize), (int)(charSize * cellSize));
  }

  /**
   * Function to deal damage to ghost
   * @param hit Damage dealt to ghost
   */
  public void TakeDamage(int hit){
        this.health -= hit;
        if(this.health <= 0)
            kill();
  }
}
